const { getDbPool } = require('../infra/dbClient');
const db = getDbPool();
const { getLogger } = require('../logger');
const logger = getLogger('utils.codeGenerator');

/**
 * 格式化日期函数
 * @param {string} pattern - 日期格式模式
 * @returns {string} 格式化后的日期字符串
 */
function formatDate(pattern) {
    const logger = getLogger('utils.codeGenerator');
    logger.debug('格式化日期', { pattern });

    const now = new Date();
    const year = now.getFullYear();
    const month = String(now.getMonth() + 1).padStart(2, '0');
    const day = String(now.getDate()).padStart(2, '0');

    // 参数验证
    if (!pattern || typeof pattern !== 'string') {
        // 默认格式：年月日
        const defaultFormat = `${year}${month}${day}`;
        logger.debug('使用默认日期格式', { defaultFormat });
        return defaultFormat;
    }

    try {
        // 记录当前日期时间信息
        logger.debug('当前日期时间信息', {
            year,
            month: parseInt(month),
            date: parseInt(day),
            hours: now.getHours(),
            minutes: now.getMinutes(),
            seconds: now.getSeconds()
        });

        // 执行格式化
        const formattedDate = pattern
            .replace('YYYY', year)
            .replace('MM', month)
            .replace('DD', day)
            .replace('HH', String(now.getHours()).padStart(2, '0'))
            .replace('mm', String(now.getMinutes()).padStart(2, '0'))
            .replace('ss', String(now.getSeconds()).padStart(2, '0'));

        logger.debug(`日期格式化完成：${formattedDate}`, { pattern, formattedLength: formattedDate.length });

        return formattedDate;
    } catch (error) {
        logger.error('日期格式化失败', {
            error: error,
            pattern,
            stack: error.stack?.substring(0, 200)
        });
        // 降级为默认格式
        const fallbackFormat = `${year}${month}${day}`;
        logger.warn(`使用降级日期格式：${fallbackFormat}`);
        return fallbackFormat;
    }
}

/**
 * 生成指定长度的序列号
 * @param {number} number - 数字
 * @param {number} length - 序列号长度
 * @returns {string} 格式化后的序列号
 */
function formatSequence(number, length) {
    return String(number).padStart(length, '0');
}

/**
 * 使用序列号表获取下一个序列号（推荐用于高并发场景）
 * @param {string} sequenceKey - 序列号键
 * @returns {Promise<number>} 下一个序列号
 */
async function getNextSequence(sequenceKey, sequenceLength = 4) {
    if (!sequenceKey || typeof sequenceKey !== 'string') {
        throw new Error('序列键参数无效');
    }
    if (typeof sequenceLength !== 'number' || sequenceLength < 1 || sequenceLength > 10) {
        sequenceLength = 4;
        logger.warn('序列长度参数无效，使用默认值', { sequenceKey, providedLength: sequenceLength });
    }
    try {
        logger.debug(`开始获取序列号: ${sequenceKey}`, { sequenceKey });
        // 先确保存在记录（懒创建），不改变 current_value
        await db.execute(
            `INSERT INTO sequence_counter (code_type, current_value, update_time)
       VALUES (?, 0, NOW())
       ON DUPLICATE KEY UPDATE update_time = NOW()`,
            [sequenceKey]
        );

        // 原子递增并取回新值
        const [updateResult] = await db.execute(
            `UPDATE sequence_counter 
       SET current_value = LAST_INSERT_ID(current_value + 1), update_time = NOW()
       WHERE code_type = ?`,
            [sequenceKey]
        );

        // 读取 LAST_INSERT_ID() 获取递增后的值
        const [idRows] = await db.execute('SELECT LAST_INSERT_ID() AS seq');
        const nextValue = idRows && idRows[0] && Number(idRows[0].seq) ? Number(idRows[0].seq) : 1;
        logger.debug(`获取到下一个序列号: ${nextValue}`, { sequenceKey });
        return nextValue;
    } catch (error) {
        logger.error('获取序列号失败，使用降级方案', { error: error, sequenceKey });

        // 使用内存计数器作为降级方案
        try {
            // 初始化全局计数器对象
            if (typeof global.sequenceCounters !== 'object' || global.sequenceCounters === null) {
                global.sequenceCounters = {};
                logger.info('初始化全局序列计数器对象');
            }

            // 为特定序列键初始化计数器
            if (typeof global.sequenceCounters[sequenceKey] !== 'number') {
                global.sequenceCounters[sequenceKey] = 0; // 初始化为0，因为下面会+1
                logger.info(`初始化序列计数器: ${sequenceKey} = 0`);
            }

            // 获取并递增计数器（先递增再返回）
            global.sequenceCounters[sequenceKey] += 1;
            const counterValue = global.sequenceCounters[sequenceKey];

            logger.info('使用内存计数器获取序列号', { sequenceKey, counterValue, currentCounter: global.sequenceCounters[sequenceKey] });
            return counterValue;
        } catch (fallbackError) {
            logger.error('降级方案也失败', { fallbackError: fallbackError.message, sequenceKey });
            return 1;
        }
    }
}

/**
 * 从数据库获取当前最大序列号（兼容旧方案）
 * @param {string} table - 表名
 * @param {string} field - 字段名
 * @param {string} likePattern - 查询模式
 * @param {string} prefixLength - 前缀长度
 * @param {string} datePartLength - 日期部分长度
 * @returns {Promise<number>} 当前最大序列号
 */
async function getMaxSequenceFromDB(table, field, likePattern, prefixLength, datePartLength) {
    try {
        const sql = `
      SELECT MAX(${field}) as maxCode 
      FROM ${table} 
      WHERE ${field} LIKE ? AND is_delete = 0
    `;

        logger.debug('尝试获取最大序列号', { table, field, likePattern });
        const [rows] = await db.execute(sql, [likePattern]);

        if (!rows[0].maxCode) {
            logger.debug('未找到匹配的编码，从0开始', { table, field, likePattern });
            return 0; // 如果没有找到匹配的编码，从0开始
        }

        // 提取序列号部分
        const code = rows[0].maxCode;
        const sequencePart = code.substring(prefixLength + datePartLength);
        const maxSequence = parseInt(sequencePart) || 0;

        logger.debug(`获取到最大序列号: ${maxSequence}`, { table, field, code });
        return maxSequence;
    } catch (error) {
        logger.error('从数据库获取最大序列号失败', { error, table, field });
        return 0;
    }
}

module.exports = {
    formatDate,
    formatSequence,
    getMaxSequenceFromDB,
    getNextSequence
};